package com.remote.ui.core.manager;

import com.remote.common.command.handler.CommandContext;
import com.remote.common.exception.RemoteException;
import com.remote.common.util.TaskExecutors;
import com.remote.ui.core.ControllerComponent;
import com.remote.ui.core.ControllerManager;
import com.remote.ui.core.ControllerRunnable;
import com.remote.ui.core.ControllerStarter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

public class AppControllerManager implements ControllerManager {
    private final Map<String, ControllerStarter> starterMap = new ConcurrentHashMap<>();
    private final Map<String, ScheduledFuture<?>> taskMap = new HashMap<>();
    private List<ControllerComponent> controllerComponents = new ArrayList<>();
    private CommandContext commandContext;


    public AppControllerManager(CommandContext commandContext) {
        this.commandContext = commandContext;
    }

    @Override
    public void addComponent(ControllerComponent controllerComponent) {
        controllerComponent.setControllerManager(this);
        controllerComponents.add(controllerComponent);
        commandContext.addReadListener(controllerComponent);
    }

    @Override
    public ControllerStarter getStarter(String fxml) {
        try {
            ControllerStarter controllerStarter = null;
            if (!starterMap.containsKey(fxml)) {
                controllerStarter = new AppControllerStarter(this, fxml);
                starterMap.put(fxml, controllerStarter);
            } else {
                controllerStarter = starterMap.get(fxml);
            }
            return controllerStarter;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ScheduledFuture<?> getTaskOrRun(String taskName, long delay, long period, ControllerRunnable uiRunnable) throws RemoteException {
        try {
            ScheduledFuture<?> scheduledFuture = null;
            if (!taskMap.containsKey(taskName)) {
                uiRunnable.setControllerManager(this);
                scheduledFuture = TaskExecutors.submit(uiRunnable, delay, period);
                taskMap.put(taskName, scheduledFuture);
            } else {
                scheduledFuture = taskMap.get(taskName);
            }
            return scheduledFuture;
        } catch (Throwable e) {
            throw new RemoteException(e);
        }
    }

    @Override
    public CommandContext getCommandContext() {
        return commandContext;
    }
}
